package com.glela.gaoweiqi;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.LogManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import com.base.BaseTest;
import com.glela.api.pay.alipay.component.Alipay;
import com.glela.api.pay.wechat.component.WeChat;
import com.glela.api.pay.wechat.component.impl.WeChat0Impl;
import com.glela.api.pay.wechat.component.impl.WeChatImpl;
import com.glela.api.pay.yeepay.component.YeePay;
import com.glela.common.constant.PayTypeEnum;
import com.glela.common.util.ExcelUtil;
import com.glela.common.util.ListUtils;
import com.glela.company.service.CompanyService;
import com.glela.company.service.XzNotifyLogService;
import com.glela.company.service.XzOmsLogService;
import com.glela.goods.mapper.GoodsMapper;
import com.glela.goods.mapper.GoodsNavigateMapper;
import com.glela.goods.mapper.InventoryMapper;
import com.glela.goods.mapper.LimitTimeSaleDetailMapper;
import com.glela.goods.mapper.ProductMapper;
import com.glela.goods.mapper.ShoppingCartMapper;
import com.glela.goods.service.BrandService;
import com.glela.goods.service.CategoryService;
import com.glela.goods.service.GoodsService;
import com.glela.goods.service.LimitTimeSaleService;
import com.glela.goods.service.ShoppingCartService;
import com.glela.order.dao.OrderDao;
import com.glela.order.mapper.AfterSalesMapper;
import com.glela.order.mapper.CommisionMapper;
import com.glela.order.mapper.OrderDetailMapper;
import com.glela.order.mapper.OrderInfoMapper;
import com.glela.order.mapper.OrderObjectMapper;
import com.glela.order.mapper.OrderPayMapper;
import com.glela.order.mapper.OrderSettlementMapper;
import com.glela.order.model.AfterSales;
import com.glela.order.model.OrderObject;
import com.glela.order.service.AfterSalesService;
import com.glela.order.service.CommissionService;
import com.glela.order.service.OrderPayService;
import com.glela.order.service.OrderService;
import com.glela.platform.mapper.BaseRestrictionsMapper;
import com.glela.platform.mapper.CUserPointTransactionMapper;
import com.glela.platform.mapper.OperationLogMapper;
import com.glela.platform.mapper.UserJournalMapper;
import com.glela.platform.mapper.UserMapper;
import com.glela.platform.mapper.UserMoneyMapper;
import com.glela.platform.mapper.UserMoneySnapshotMapper;
import com.glela.platform.mapper.UserPointJournalMapper;
import com.glela.platform.service.AdvertisementService;
import com.glela.platform.service.BaseRestrictionsService;
import com.glela.platform.service.CUserPointTransactionService;
import com.glela.platform.service.TalentJobSerice;
import com.glela.platform.service.UnifiedTreatmentService;
import com.glela.platform.service.UserAddressService;
import com.glela.platform.service.UserJournalService;
import com.glela.platform.service.UserService;
import com.glela.platform.service.VersionService;
import com.glela.serial.service.DiscoveryTypeService;
import com.glela.serial.service.SerialGoodService;
import com.glela.serial.service.SerialService;
import com.glela.serial.service.TitleDiscoveryService;
import com.glela.statistics.mapper.OrderStatisticsMapper;
import com.glela.statistics.service.StatisticsService;
import com.glela.talent.util.MyDateUtil;
import com.glela.test.ValidationAfterSale;
import com.glela.test.ValidationCannelOrder;
import com.glela.test.ValidationOrder;
import com.glela.test.ValidationUser;

public class gwqTestDemo extends BaseTest {
//	private static Logger logger = LoggerFactory.getLogger(gwqTestDemo.class);
	private static org.apache.log4j.Logger logger=LogManager.getLoggerRepository().getLogger("gwqTestDemo");
	private static SimpleDateFormat	df	= new SimpleDateFormat("yyyy年MM月dd日hh时mm分ss秒");
	@Autowired
	private List<OrderService> orderServiceList;
	@Autowired
	private List<WeChat> weChatList;
	@Autowired
	private List<StatisticsService> statisticsServiceList;
	@Autowired
	private UserMoneySnapshotMapper userMoneySnapshotMapper;
	@Autowired
	private CUserPointTransactionMapper cUserPointTransactionMapper;
	@Autowired
	private OrderStatisticsMapper orderStatisticsMapper;
	@Autowired
	private OrderPayMapper orderPayMapper;
	@Autowired
	private TalentJobSerice talentJobSerice;
	@Autowired
	private XzOmsLogService xzOmsLogService;
	@Autowired
	private UserService userService;
	@Autowired
	private InventoryMapper inventoryMapper;
	@Autowired
	private UserMapper userMapper;
	@Autowired
	private UserJournalService userJournalService;
	@Autowired
	private UnifiedTreatmentService unifiedTreatmentService;
	@Autowired
	private ShoppingCartService shoppingCartService;
	@Autowired
	private UserMoneyMapper userMoneyMapper;
	@Autowired
	private OperationLogMapper operationLogMapper;
	@Autowired
	private LimitTimeSaleDetailMapper limitTimeSaleDetailMapper;
	@Autowired
	private AfterSalesService afterSalesService;
	@Autowired
	private CommissionService commissionService;
	@Autowired
	private Alipay alipay;
	@Autowired
	private GoodsNavigateMapper goodsNavigateMapper;
	@Autowired
	protected OrderDao orderDao;
	@Autowired
	private GoodsService goodsService;
	@Autowired
	private UserJournalMapper userJournalMapper;
	@Autowired
	private OrderPayService orderPayService;
	@Autowired
	private OrderObjectMapper orderObjectMapper;
	@Autowired
	private OrderInfoMapper orderInfoMapper;
	@Autowired
	private OrderSettlementMapper oderSettlementMapper;
	@Resource(name = "orderService2")
	private OrderService orderService2;
	@Resource(name = "orderService5")
	private OrderService orderService5;
	@Autowired
	protected YeePay yeePay;
	@Autowired
	private XzNotifyLogService xzNotifyLogService;
	@Autowired
	private SerialGoodService serialGoodService;
	@Autowired
	private DiscoveryTypeService discoveryTypeService;
	@Autowired
	private TitleDiscoveryService titleDiscoveryService;
	@Autowired
	private AdvertisementService advertisementService;
	@Autowired
	private BaseRestrictionsService baseRestrictionsService;
	@Autowired
	private ShoppingCartMapper shoppingCartMapper;
	@Autowired
	private ProductMapper productMapper;
	@Autowired
	private CategoryService categoryService;
	@Autowired
	private CompanyService companyService;
	@Autowired
	private GoodsMapper goodsMapper;
	@Autowired
	private BrandService brandService;
	@Autowired
	private UserAddressService userAddressService;
	@Autowired
	private SerialService serialService;
	@Autowired
	private VersionService versionService;
	@Autowired
	private BaseRestrictionsMapper baseRestrictionsMapper;
	@Autowired
	private LimitTimeSaleService limitTimeSaleService;
	@Autowired
	private OrderSettlementMapper orderSettlementMapper;
	@Autowired
	private AfterSalesMapper afterSalesMapper;
	@Autowired
	private CommisionMapper commisionMapper;
	@Autowired
	private OrderDetailMapper orderDetailMapper;
	@Autowired
	private CUserPointTransactionService cUserPointTransactionService;
	@Autowired
	private UserPointJournalMapper userPointJournalMapper;
	@Autowired
	private ThreadPoolTaskExecutor ThreadPool;
	@Autowired
	private Map<String, OrderService> orderServiceMap;
	private static MyDateUtil util = MyDateUtil.INSTANCE;
	@org.junit.Test
public   void main( ) {
//		String beginTime="2018-02-09 00:00:00";
//		String snapTime=util.getOldDays(-1);
//		String endTime="2018-03-01 00:00:00";
		String beginTime=util.getOldDays(1);
		String snapTime=util.getOldDays(-1);
		String endTime=util.getYesterday(new Date());
            try {
				validtionOrder(beginTime,endTime);
//				validtionUser();
//				validtionjournal(beginTime,snapTime,endTime);
			} catch (Exception e) {
				logger.info(e.getMessage());
			}	
}
	public void  validtionOrder(String beginTime,String endTime) throws  Exception{
		Map<String, List<Map<String, Object>>> results=new  HashMap<String, List<Map<String, Object>>>();
		Map<String, String[]> names=new HashMap<>(); 
		Map<String, String> keyword=new HashMap<>(); 
//		String file_name="c:/异常数据/("+df.format(new Date())+ ")订单异常.xlsx";
		String file_name=File.separator+"异常数据"+File.separator+"("+df.format(new Date())+ ")订单异常.xlsx";
		int[] statusArray={2,3,4,6,7};//支付成功的订单
		//1.验证当天的订单情况 去易宝查一下支付状态 
		long times=System.currentTimeMillis();
		List<OrderObject> listOBJ=orderObjectMapper.selectOrderObjectByStatusAndUpdateTime(statusArray,beginTime,endTime);
		logger.info("查找订单数据 "+beginTime+"--"+"endTime 耗时(秒):"+((System.currentTimeMillis()-times)/1000.0)+"  找到行数:"+listOBJ.size());
		List<Map<String, Object>> result=new  ArrayList<Map<String, Object>>();
		int  index=0;
		List<Future<List<Map<String, Object>>>>  FutureList=new ArrayList<>();
		List<OrderObject> listOBJTemp=listOBJ.size()>100?listOBJ.subList(0,index=index+100):listOBJ;
		times=System.currentTimeMillis();
		while(ListUtils.isNotEmpty(listOBJTemp)){
			ValidationOrder orderTest=new  ValidationOrder(listOBJTemp, orderService2);
			 Future<List<Map<String, Object>>>  future=ThreadPool.submit(orderTest);
			FutureList.add(future);
			listOBJTemp=listOBJ.subList(index,index=(index+100)>listOBJ.size()?(listOBJ.size()):(index+100));
		}
		while(true){
			 boolean isAllDone = true;
	            for (Future<List<Map<String, Object>>>  future : FutureList) {
	                isAllDone &= ( future.isDone() || future.isCancelled() );
	            }
	            if (isAllDone) {
	                break;
	            }
		}
		for(Future<List<Map<String, Object>>> ss:FutureList){
			try {
				result.addAll(ss.get());
			} catch (Exception e) {
				System.out.println("Exception："+e.getMessage());
			}
		}
		logger.info("耗时 :"+((System.currentTimeMillis()-times)/1000.0));
		results.put("1", result);//异常订单
		names.put("1",new  String[]{"父订单号","异常原因"});//列名
		keyword.put("1","异常订单");//sheet name
		//2. 查找所有的状态是1或者5的单子
		index=0;
		result=new ArrayList<Map<String, Object>>();
		times=System.currentTimeMillis();
		List<OrderObject> payObj=orderObjectMapper.selectOrderObjectByStatusAndUpdateTime(new int[]{1,5},beginTime,endTime);
		logger.info("查找未支付订单数据 "+beginTime+"--"+"endTime 耗时(秒):"+((System.currentTimeMillis()-times)/1000.0)+"  找到行数:"+payObj.size());
		 FutureList=new ArrayList<>();
		  listOBJTemp=payObj.size()>100?payObj.subList(0,index=index+100):payObj;
			times=System.currentTimeMillis();
			while(ListUtils.isNotEmpty(listOBJTemp)){
				ValidationCannelOrder orderTest=new  ValidationCannelOrder(listOBJTemp, orderPayMapper, orderPayService,weChatList,orderService2,alipay);
				 Future<List<Map<String, Object>>>  future=ThreadPool.submit(orderTest);
				FutureList.add(future);
				listOBJTemp=payObj.subList(index,index=(index+100)>payObj.size()?(payObj.size()):(index+100));
			}
			while(true){
				 boolean isAllDone = true;
		            for (Future<List<Map<String, Object>>>  future : FutureList) {
		                isAllDone &= ( future.isDone() || future.isCancelled() );
		            }
		            if (isAllDone) {
		                break;
		            }
			}
			for(Future<List<Map<String, Object>>> ss:FutureList){
				result.addAll(ss.get());
			}
		logger.info("耗时 :"+((System.currentTimeMillis()-times)/1000.0));
		results.put("2", result);//异常订单
		names.put("2",new  String[]{"父订单号","异常原因"});//列名
		keyword.put("2","支付异常订单");//sheet name
		//3.验证售后单 查找当天更新的售后单
		index=0;
		result=new ArrayList<Map<String, Object>>();
		times=System.currentTimeMillis();
		List<AfterSales> AfterSalesListTemp=new ArrayList<>();
		List<AfterSales> AfterSalesList=afterSalesMapper.selectAfterSalesByUpdateTime(beginTime,endTime);
		logger.info("查找售后单数据 "+beginTime+"--"+"endTime 耗时(秒):"+((System.currentTimeMillis()-times)/1000.0)+"  找到行数:"+listOBJ.size());
		AfterSalesListTemp=AfterSalesList.size()>100?AfterSalesList.subList(0,index=index+100):AfterSalesList;
		FutureList=new ArrayList<>();
		times=System.currentTimeMillis();
		while(ListUtils.isNotEmpty(AfterSalesListTemp)){
			ValidationAfterSale orderTest=new  ValidationAfterSale(AfterSalesListTemp, afterSalesService);
			 Future<List<Map<String, Object>>>  future=ThreadPool.submit(orderTest);
			FutureList.add(future);
			AfterSalesListTemp=AfterSalesList.subList(index,index=(index+100)>AfterSalesList.size()?(AfterSalesList.size()):(index+100));
		}
		while(true){
			 boolean isAllDone = true;
	            for (Future<List<Map<String, Object>>>  future : FutureList) {
	                isAllDone &= ( future.isDone() || future.isCancelled() );
	            }
	            if (isAllDone) {
	                break;
	            }
		}
		for(Future<List<Map<String, Object>>> ss:FutureList){
			result.addAll(ss.get());
		}
		logger.info("耗时 :"+((System.currentTimeMillis()-times)/1000.0));
		results.put("3", result);//异常订单
		names.put("3",new  String[]{"售后单号","异常原因"});//列名
		keyword.put("3","异常售后单");//sheet name
		ExcelUtil.writeExecl(file_name, results, names, keyword);
	}
	/**验证用户信息*/
	public void  validtionUser() throws Exception{
		Map<String, List<Map<String, Object>>> results=new  HashMap<String, List<Map<String, Object>>>();
		Map<String, String[]> names=new HashMap<>(); 
		Map<String, String> keyword=new HashMap<>(); 
		List<Map<String, Object>> result=new ArrayList<Map<String, Object>>();
		String file_name=File.separator+"异常数据"+File.separator+"("+df.format(new Date())+ ")用户异常.xlsx";
		//8 验证用户身份信息异常的用户
		result.addAll(orderStatisticsMapper.validationUserInfo());
		results.put("1", result);//异常订单
		names.put("1",new  String[]{"用户ID","登录名","登录人身份","异常原因","推荐人ID","推荐人登录账号","推荐人身份","达人导师ID","达人导师登录账号","达人导师身份"});//列名
		keyword.put("1","用户身份异常");//sheet name
		ExcelUtil.writeExecl(file_name, results, names, keyword);
	}
	/**验证用户流水*/
	public void  validtionjournal(String beginTime,String snapTime,String endTime) throws Exception{
		Map<String, List<Map<String, Object>>> results=new  HashMap<String, List<Map<String, Object>>>();
		Map<String, String[]> names=new HashMap<>(); 
		Map<String, String> keyword=new HashMap<>(); 
		List<Map<String, Object>> result=new ArrayList<Map<String, Object>>();
//		String file_name="c:/异常数据/("+df.format(new Date())+ ")用户流水异常.xlsx";
		String file_name=File.separator+"异常数据"+File.separator+"("+df.format(new Date())+ ")流水异常.xlsx";
		//6.验证账户的余额妆币流水变化过程
		//验证账户余额变化过程异常(某一时刻 期初减期末成为负数)
		List<Map<Object, Object>> MoneyProcessMap=orderStatisticsMapper.validationUserMoneyProcess();
		List<Map<Object, Object>> PointProcessMap=orderStatisticsMapper.validationUserPointProcess();
		long userID=0L;//当前正在计算中的用户ID
		long ErrorUserID=0L;//当前流水发生错误的用户ID
		int  UserMoney=0;
		for(Map<Object, Object> temp:MoneyProcessMap){ 
			long TempUserID=temp.get("user_id")==null?0:Long.parseLong(temp.get("user_id").toString());
			int TempMoney=temp.get("money")==null?0:Integer.parseInt(temp.get("money").toString());
			String Flag=temp.get("type")==null?"":temp.get("type").toString();
			if(TempUserID==0L||TempUserID==0||!"+-".contains(Flag)){
				continue;
			}
			if(ErrorUserID==TempUserID){//当前的用户上一条流水已经发生错误了
				continue;
			}
			
			if(TempUserID!=userID){//开始判断下一个用户的流水 重置数据
				userID=TempUserID;
				UserMoney=0;
			}
			//但比计算逻辑
			if("+".equals(Flag)){
				UserMoney+=TempMoney;
			}else{
				UserMoney-=TempMoney;
			}
			//当前的流水异常  异常流水从2018年初开始算
			if(UserMoney<0&&StringUtils.compare(temp.get("create_time").toString(),"2018-01-01 00:00:00")>0){
				ErrorUserID=TempUserID;
				Map<String, Object> maps=new  HashMap<String, Object>();
				maps.put("1",String.valueOf(ErrorUserID));
				maps.put("2", "用户余额流水异常 用户ID :"+ErrorUserID+" 异常流水ID: "+temp.get("id"));
				result.add(maps);
			}
		}
			results.put("1", result);//异常订单
			names.put("1",new  String[]{"用户ID","异常原因"});//列名
			keyword.put("1","用户余额流水异常");//sheet name
			
		result=new ArrayList<Map<String, Object>>();
		 userID=0L;ErrorUserID=0L;UserMoney=0;
		for(Map<Object, Object> temp:PointProcessMap){ 
			long TempUserID=temp.get("user_id")==null?0:Long.parseLong(temp.get("user_id").toString());
			int TempMoney=temp.get("amount")==null?0:Integer.parseInt(temp.get("amount").toString());
			if(TempUserID==0L||TempUserID==0){
				continue;
			}
			if(ErrorUserID==TempUserID){//当前的用户上一条流水已经发生错误了
				continue;
			}
			
			if(TempUserID!=userID){//开始判断下一个用户的流水 重置数据
				userID=TempUserID;
				UserMoney=0;
			}
			//但比计算逻辑
				UserMoney+=TempMoney;
			//当前的流水异常
			if(UserMoney<0&&StringUtils.compare(temp.get("create_time").toString(),"2018-01-01 00:00:00")>0){
				ErrorUserID=TempUserID;
				Map<String, Object> maps=new  HashMap<String, Object>();
				maps.put("1",String.valueOf(ErrorUserID));
				maps.put("2", "用户妆币流水异常 用户ID :"+ErrorUserID+" 异常流水ID: "+temp.get("id"));
				result.add(maps);
			}
		}
			results.put("2", result);//异常订单
			names.put("2",new  String[]{"用户ID","异常原因"});//列名
			keyword.put("2","用户妆币流水异常");//sheet name
		//2 验证账户金额和流水不一致的用户
		List<Map<String,Object>> listUserTh=userMoneyMapper.validationUserMoney();
			results.put("3", listUserTh);//异常订单
			names.put("3",new  String[]{"用户ID","余户余额","余额流水","用户妆币","妆币流水"});//列名
			keyword.put("3","账户金额和流水不一致的用户");//sheet name
		//1 验证当天的快照是否有异常 保证当天的快照和账户余额流水能够核对的上
		List<Map<Object, Object>> vlidationSnapShotList=userMoneySnapshotMapper.ValidationSnapShot(beginTime,snapTime,endTime);
			result=new ArrayList<Map<String, Object>>();
			for(Map<Object, Object> maps:vlidationSnapShotList){
				Map<String,Object> tempMap=new HashMap<String,Object>();
				tempMap.put("1",maps.get("user_id").toString());
				tempMap.put("2","用户当日快照异常");
				result.add(tempMap);
			}
				results.put("4", result);//异常订单
				names.put("4",new  String[]{"用户ID","异常原因"});//列名
				keyword.put("4","妆币快照异常");//sheet name
		ExcelUtil.writeExecl(file_name, results, names, keyword);
	}
}
